package game.lan;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.common.StringConstants;
import game.entity.PlayingRole;
import game.lan.msg.DdzStart2RsMessage;
import game.lan.msg.MjStart2RsMessage;
import game.lan.msg.NnStart2RsMessage;
import game.lan.msg.QzmjStart2RsMessage;
import game.lan.msg.SssStart2RsMessage;
import game.module.ddz.bean.DdzRoom;
import game.module.ddz.logic.DdzLogic;
import game.module.hall.dao.OnlineCountCache;
import game.module.hall.logic.HallManager;
import game.module.mj.bean.MjRoom;
import game.module.mj.logic.MjLogic;
import game.module.nn.bean.NnRoom;
import game.module.nn.logic.NnLogic;
import game.module.offline.bean.PlayerOfflineCache;
import game.module.offline.logic.PlayerOfflineManager;
import game.module.qzmj.bean.QzmjRoom;
import game.module.qzmj.logic.QzmjLogic;
import game.module.sss.bean.SssRoom;
import game.module.sss.logic.SssLogic;
import game.session.SessionManager;
import io.netty.channel.Channel;
import lion.lan.ILanIoExecutor;
import lion.lan.LanClientSession;
import lion.lan.Netty4LanClient;
import lion.netty4.message.RequestMessage;
import lion.netty4.message.SendToMessage;

public class HallLanClientManager implements ILanIoExecutor {

	private Netty4LanClient lanClient;

	private Map<String, LanClientSession> gsConnectionSessionMap = new HashMap<String, LanClientSession>();

	private static Logger logger = LoggerFactory.getLogger(HallLanClientManager.class);

	public HallLanClientManager() {
		lanClient = new Netty4LanClient(this, null);
	}

	public void shutdown() {
		if (lanClient != null) {
			lanClient.close();
		}
	}

	public boolean connect(String host, int port) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap.get(host + StringConstants.SEPARATOR_DI + port);
		if (gsConnectionSession == null) {
			gsConnectionSession = new LanClientSession(lanClient);
			gsConnectionSessionMap.put(host + StringConstants.SEPARATOR_DI + port, gsConnectionSession);
		}
		// already connected
		if (gsConnectionSession.isConnected()) {
			return true;
		}
		boolean ret = false;
		synchronized (gsConnectionSession) {
			try {
				gsConnectionSession.connect(host, port);
				ret = true;
			} catch (Exception e) {
				logger.error("lan connect to " + host + ":" + port + " error!", e);
			}
		}
		return ret;
	}

	@Override
	public void execute(Channel channel, RequestMessage msg) throws IOException {
		logger.info("reveive msgCode={}", msg.getMsgCode());
		switch (msg.getMsgCode()) {
		case 302:
			DdzLogic.getInstance().lanDdzStartBack(msg);
			break;
		case 304:
			NnLogic.getInstance().lanNnGenerateCardsBack(msg);
			break;
		case 306:
			SssLogic.getInstance().lanGenerateCardsBack(msg);
			break;
		case 308:
			MjLogic.getInstance().lanMjGenerateCardsBack(msg);
			break;
		case 310:
			int opType = msg.readInt();
			int playerId = msg.readInt();
			int roomType = msg.readInt();
			long roomSessionId = msg.readLong();
			logger.info("room type back,opType={},playerId={},type={}", opType, playerId, roomType);
			HallManager.getInstance().roomTypeBack(opType, playerId, roomType,roomSessionId);
			break;
		case 312:
			int ddzCount = msg.readInt();
			int nnCount = msg.readInt();
			int sssCount = msg.readInt();
			int mjCount = msg.readInt();
			logger.info("online player count check,ddz={},nn={},sss={},mj={}", ddzCount, nnCount, sssCount, mjCount);
			OnlineCountCache.getInstance().setOnlineCount(ddzCount, nnCount, sssCount, mjCount);
			break;
		case 314:
			QzmjLogic.getInstance().lanQzGenerateCardsBack(msg);
			break;
		default:
			break;
		}
	}

	public void sendCraftCancel2Cross(String crossHost, int crossPort, Integer playerId, Integer serverId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(crossHost + StringConstants.SEPARATOR_DI + crossPort);
		SendToMessage sendToMessage = new SendToMessage(gsConnectionSession.alloc(), 30003);
		sendToMessage.writeInt(playerId);
		sendToMessage.writeInt(serverId);
		gsConnectionSession.writeAndFlush(sendToMessage);
	}

	public void sendCrossBossView2Cross(String crossHost, int crossPort, int playerId, Integer serverId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(crossHost + StringConstants.SEPARATOR_DI + crossPort);
		SendToMessage sendToMessage = new SendToMessage(gsConnectionSession.alloc(), 30007);
		sendToMessage.writeInt(playerId);
		sendToMessage.writeInt(serverId);
		// send
		gsConnectionSession.writeAndFlush(sendToMessage);
	}

	public void sendPay2Ls(String loginHost, long loginPort, long randOrderId, int serverId, String openId,
			int productId) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(loginHost + StringConstants.SEPARATOR_DI + loginPort);
		SendToMessage sendToMessage = new SendToMessage(gsConnectionSession.alloc(), 11001);
		sendToMessage.writeLong(randOrderId);
		sendToMessage.writeInt(serverId);
		sendToMessage.writeString(openId);
		sendToMessage.writeInt(productId);
		// send
		gsConnectionSession.writeAndFlush(sendToMessage);
	}

	public void sendDdzStart2Rs(String hostName, int port, DdzRoom ddzRoom) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		DdzStart2RsMessage gsMessage = new DdzStart2RsMessage(gsConnectionSession.alloc());
		gsMessage.setRoomId(ddzRoom.getUuid());
		List<Integer> playerIdList = ddzRoom.getPlayerList();
		gsMessage.writeInt(playerIdList.size());
		for (Integer aPlayerId : playerIdList) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			gsMessage.writeInt(aPlayerId);
			PlayerOfflineCache poc = PlayerOfflineManager.getInstance().getPlayerOfflineCache(aPlayerId);
			gsMessage.writeString(poc.getName());
			gsMessage.writeInt(poc.getSex());
			gsMessage.writeString(poc.getHeadimg());
			gsMessage.writeLong(pr.getGamePlayer().getSessionId());
		}
		gsMessage.writeShort(ddzRoom.getRoundCount());
		gsMessage.writeByte(ddzRoom.getJiaoOrQiang());
		logger.info("send Ddz Start2Rs,host={},roomId={}", hostName, ddzRoom.getUuid());
		gsConnectionSession.writeAndFlush(gsMessage);
	}

	public void sendNnStart2Rs(String hostName, int port, NnRoom ddzRoom) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		NnStart2RsMessage gsMessage = new NnStart2RsMessage(gsConnectionSession.alloc());
		gsMessage.setRoomId(ddzRoom.getUuid());
		List<Integer> playerIdList = ddzRoom.getPlayerList();
		gsMessage.writeShort(ddzRoom.getRoundCount());
		gsMessage.writeByte(ddzRoom.getRoomFeeType());
		gsMessage.writeInt(ddzRoom.getRoomfee());
		gsMessage.writeByte(ddzRoom.getIs_jindou());
		gsMessage.writeInt(ddzRoom.getJindou());
		gsMessage.writeInt(playerIdList.size());
		for (Integer aPlayerId : playerIdList) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			gsMessage.writeInt(aPlayerId);
			PlayerOfflineCache poc = PlayerOfflineManager.getInstance().getPlayerOfflineCache(aPlayerId);
			gsMessage.writeString(poc.getName());
			gsMessage.writeInt(poc.getSex());
			gsMessage.writeString(poc.getHeadimg());
			gsMessage.writeLong(pr.getGamePlayer().getSessionId());
		}
		logger.info("send nn Start2Rs,host={},roomId={}", hostName, ddzRoom.getUuid());
		gsConnectionSession.writeAndFlush(gsMessage);
	}

	public void sendSssStart2Rs(String hostName, int port, SssRoom ddzRoom) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		SssStart2RsMessage gsMessage = new SssStart2RsMessage(gsConnectionSession.alloc());
		gsMessage.setRoomId(ddzRoom.getUuid());
		gsMessage.writeShort(ddzRoom.getRoundCount());
		gsMessage.writeByte(ddzRoom.getPrevent_cheat());
		gsMessage.writeByte(ddzRoom.getMapai());
		gsMessage.writeByte(ddzRoom.getDaqiang());
		gsMessage.writeByte(ddzRoom.getSunzi_a());
		gsMessage.writeByte(ddzRoom.getBaodao());
		gsMessage.writeByte(ddzRoom.getIs_jindou());
		gsMessage.writeInt(ddzRoom.getJindou());
		gsMessage.writeInt(ddzRoom.getRoomFee());
		gsMessage.writeByte(ddzRoom.getRoomFeeType());
		gsMessage.writeByte(ddzRoom.getPlayer_count());
		gsMessage.writeBytes(ddzRoom.getAdd_color());
		List<Integer> playerIdList = ddzRoom.getPlayerList();
		gsMessage.writeInt(playerIdList.size());
		for (Integer aPlayerId : playerIdList) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			gsMessage.writeInt(aPlayerId);
			PlayerOfflineCache poc = PlayerOfflineManager.getInstance().getPlayerOfflineCache(aPlayerId);
			gsMessage.writeString(poc.getName());
			gsMessage.writeInt(poc.getSex());
			gsMessage.writeString(poc.getHeadimg());
			gsMessage.writeLong(poc.getJindou());
			gsMessage.writeLong(pr.getGamePlayer().getSessionId());
		}
		logger.info("send sss Start2Rs,host={},roomId={}", hostName, ddzRoom.getUuid());
		gsConnectionSession.writeAndFlush(gsMessage);
	}

	public void sendMjStart2Rs(String hostName, int port, MjRoom ddzRoom) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		MjStart2RsMessage gsMessage = new MjStart2RsMessage(gsConnectionSession.alloc());
		gsMessage.setRoomId(ddzRoom.getUuid());
		gsMessage.writeShort(ddzRoom.getRoundCount());
		gsMessage.writeByte(ddzRoom.getDapai());
		gsMessage.writeByte(ddzRoom.getTypehu());
		gsMessage.writeByte(ddzRoom.getPrevent_cheat());
		gsMessage.writeInt(ddzRoom.getGold_rate());
		gsMessage.writeByte(ddzRoom.getCost_type());
		List<Integer> playerIdList = ddzRoom.getPlayerList();
		gsMessage.writeInt(playerIdList.size());
		for (Integer aPlayerId : playerIdList) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			gsMessage.writeInt(aPlayerId);
			PlayerOfflineCache poc = PlayerOfflineManager.getInstance().getPlayerOfflineCache(aPlayerId);
			gsMessage.writeString(poc.getName());
			gsMessage.writeInt(poc.getSex());
			gsMessage.writeString(poc.getHeadimg());
			gsMessage.writeLong(pr.getGamePlayer().getSessionId());
		}
		logger.info("send mj Start2Rs,host={},roomId={}", hostName, ddzRoom.getUuid());
		gsConnectionSession.writeAndFlush(gsMessage);
	}
	public void sendQzmjStart2Rs(String hostName, int port, QzmjRoom ddzRoom) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		QzmjStart2RsMessage gsMessage = new QzmjStart2RsMessage(gsConnectionSession.alloc());
		gsMessage.setRoomId(ddzRoom.getUuid());
		gsMessage.writeShort(ddzRoom.getRoundCount());
		gsMessage.writeByte(ddzRoom.getSanjindao());
		gsMessage.writeByte(ddzRoom.getEat_card());
		gsMessage.writeByte(ddzRoom.getHua_card());
		gsMessage.writeByte(ddzRoom.getPrevent_cheat());
		gsMessage.writeInt(ddzRoom.getGold_coin());
		gsMessage.writeByte(ddzRoom.getCost_type());
		gsMessage.writeByte(ddzRoom.getYoujin());
		gsMessage.writeShort(ddzRoom.getFee());
		Map<Integer,String> ipmap = ddzRoom.getIpmaps();
		List<Integer> playerIdList = ddzRoom.getPlayerList();
		gsMessage.writeInt(playerIdList.size());
		for (Integer aPlayerId : playerIdList) {
			PlayingRole pr = SessionManager.getInstance().getPlayer(aPlayerId);
			gsMessage.writeInt(aPlayerId);
			PlayerOfflineCache poc = PlayerOfflineManager.getInstance().getPlayerOfflineCache(aPlayerId);
			gsMessage.writeString(poc.getName());
			gsMessage.writeInt(poc.getSex());
			gsMessage.writeString(poc.getHeadimg());
			gsMessage.writeString(ipmap.get(aPlayerId));
			gsMessage.writeLong(pr.getGamePlayer().getSessionId());
		}
		logger.info("send qzmj Start2Rs,host={},roomId={}", hostName, ddzRoom.getUuid());
		gsConnectionSession.writeAndFlush(gsMessage);
	}
	public void sendCheckRoomType2Rs(String hostName, int port,int playerId, int opType) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		SendToMessage rsMessage = new SendToMessage(gsConnectionSession.alloc(), 309);
		rsMessage.writeInt(opType);
		rsMessage.writeInt(playerId);
		logger.info("send Check RoomType 2 Rs,host={},playerId={}", hostName, playerId);
		gsConnectionSession.writeAndFlush(rsMessage);
	}
	
	public void queryPlayerCount2Rs(String hostName, int port) {
		LanClientSession gsConnectionSession = gsConnectionSessionMap
				.get(hostName + StringConstants.SEPARATOR_DI + port);
		SendToMessage rsMessage = new SendToMessage(gsConnectionSession.alloc(), 311);
		logger.info("send query Player Count 2 Rs,host={},port={}", hostName, port);
		gsConnectionSession.writeAndFlush(rsMessage);
	}
	
}